package com.stottlerhenke.simbionic.engine.core;

import com.stottlerhenke.simbionic.engine.manager.*;
import com.stottlerhenke.simbionic.engine.parser.*;
import com.stottlerhenke.simbionic.api.SB_Exception;
import com.stottlerhenke.simbionic.engine.SB_CoreInterface;

import java.io.Serializable;
import java.util.*;

/**
 * <p>Title: A class to keep track of and perform delayed actions </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Stottler Henke</p>
 * @author unascribed
 * @version 1.0
 */

public class SB_DelayedAction implements Serializable 
{

  private int _id;
  private ArrayList _variables; //Array of SB_Variable objects
  private boolean _predicate;

  public SB_DelayedAction(int id, ArrayList variables, boolean bPredicate)
  {
    _id = id;
    _variables = variables;
    _predicate = bPredicate;
  }

  public void DoDelayedAction(SB_EntityManager mgr) throws SB_Exception
  {
    //@todo Add debugging message
  	//@todo Modify parameters such that SB_Param, not SB_Variables are passed in to avoid translating twice

    if( _predicate )
    {
      if(_id == SB_CoreInterface.PRED_CreateEntity)
      {
        CreateEntity
        (   mgr,
            (SB_VarEntity)  _variables.get(5),
            (SB_VarString)_variables.get(0),
            (SB_VarString) _variables.get(1),
            (ArrayList) _variables.get(2),
            ((SB_VarInteger) _variables.get(3)).GetValue(),
            ((SB_VarInteger) _variables.get(4)).GetValue()
        );
      }
      else
        throw new SB_Exception("Call to illegal core delayed predicate ID %d." + _id);
    }
    else
    {
      if(_id == SB_CoreInterface.ACTION_SetEntityGlobal )
      {
        SetEntityGlobal(mgr, (SB_VarEntity) _variables.get(0), (SB_VarString) _variables.get(1), (SB_Variable)  _variables.get(2));
      }
      else
          if(_id == SB_CoreInterface.ACTION_PushBehavior)
          {
            PushBehavior(mgr, (SB_VarEntity) _variables.get(0), (SB_VarString) _variables.get(1), (ArrayList)_variables.get(2));
          }
      else
      if(_id == SB_CoreInterface.ACTION_SetBehavior)
      {
        SetBehavior(mgr, (SB_VarEntity) _variables.get(0), (SB_VarString) _variables.get(1), (ArrayList)_variables.get(2));
      }
      else
      if(_id == SB_CoreInterface.ACTION_SetUpdateFrequency)
      {
        SetUpdateFreq(mgr, ((SB_VarInteger) _variables.get(0)).GetValue(), (SB_VarEntity) _variables.get(1) );
      }
      else
      if(_id == SB_CoreInterface.ACTION_SetUpdatePriority)
      {
        SetUpdatePriority( mgr, ((SB_VarInteger) _variables.get(0)).GetValue(), (SB_VarEntity) _variables.get(1) );
      }
      else
      if(_id == SB_CoreInterface.ACTION_DestroyEntity)
      {
        DestroyEntity( mgr, (SB_VarEntity) _variables.get(0) );
      }
      else
        throw new SB_Exception("Call to illegal core delayed action ID %d." + _id);
    }
  }

  void CreateEntity( SB_EntityManager mgr, SB_VarEntity newId, SB_VarString entityName, SB_VarString behaviorId, ArrayList params,int updateFreq,int updatePriority) throws SB_Exception
  {
     mgr.createEntity(newId.GetValue(), entityName.GetValue(),behaviorId.GetValue(),params,updateFreq,updatePriority);
  }

  void SetEntityGlobal(SB_EntityManager mgr, SB_VarEntity entityId, SB_VarString varName,SB_Variable value) throws SB_Exception
  {
    mgr.SetGlobal(entityId.GetValue(), varName.GetValue(), value );
  }

  void PushBehavior(SB_EntityManager mgr, SB_VarEntity entityId, SB_VarString behaviorId,ArrayList params) throws SB_Exception
  {
    mgr.PushBehavior(entityId.GetValue(), behaviorId.GetValue(), params );
  }

  void SetBehavior(SB_EntityManager mgr, SB_VarEntity entityId, SB_VarString behaviorId,ArrayList params) throws SB_Exception
  {
    mgr.SetBehavior(entityId.GetValue(), behaviorId.GetValue(), params );
  }

  void SetUpdateFreq(SB_EntityManager mgr, int newFreq, SB_VarEntity entityId) throws SB_Exception
  {
    mgr.SetUpdateFreq(newFreq, entityId.GetValue());
  }

  void SetUpdatePriority(SB_EntityManager mgr, int newPriority, SB_VarEntity entityId) throws SB_Exception
  {
    mgr.SetUpdatePriority(newPriority, entityId.GetValue());
  }

  void DestroyEntity(SB_EntityManager mgr, SB_VarEntity entityId) throws SB_Exception
  {
    mgr.DestroyEntity( entityId.GetValue() );
  }
  
  public String toString()
  {
      return convertIdToString() + _variables.toString();
  }
  
  public String convertIdToString()
  {
      switch(_id)
      {
      case SB_CoreInterface.PRED_CreateEntity:
          return "CreateEntity";
      case SB_CoreInterface.ACTION_SetEntityGlobal:
          return "SetEntityGlobal";
      case SB_CoreInterface.ACTION_PushBehavior:
          return "PushBehavior";
      case SB_CoreInterface.ACTION_SetBehavior:
          return "SetBehavior";
      case SB_CoreInterface.ACTION_SetUpdateFrequency:
          return "SetUpdateFrequency";
      case SB_CoreInterface.ACTION_SetUpdatePriority:
          return "SetUpdatePriority";
      case SB_CoreInterface.ACTION_DestroyEntity:
          return "DestroyEntity";
      }
      
      return "Unknown action/predicate";
  }
}